<?php

namespace app\admin\controller\course;

use app\admin\controller\Api;
use app\common\controller\Backend;
use app\common\model\CourseSchedule;
use app\admin\model\Ocation;
use think\Db;
use think\Exception;
use think\exception\PDOException;
use think\exception\ValidateException;
use app\admin\library\CommunityScheduler;
use app\admin\library\CommunityRedis;

/**
 * 课程排期管理
 *
 * @icon fa fa-calendar-check-o
 */
class Schedule extends Backend
{
    /**
     * CourseSchedule模型对象
     * @var \app\common\model\CourseSchedule
     */
    protected $model = null;
    protected $redis = null;
    protected $communityScheduler = null;
    protected $noNeedRight = ['clear', 'getSubjectList', 'getCommunityList', 'export', 'generate', 'confirmSchedule', 'checkFormalSchedule', 'cancelSchedule'];
    protected $noNeedLogin = [
        'clear',
        'getSubjectList',
        'getCommunityList',
        'export',
        'generate',
        'confirmSchedule',
        'checkFormalSchedule',
        'cancelSchedule'
    ];
    public $timeSlotDetails = [];

    /**
     * 检查排课是否已过期
     * @param array|int $schedule 排课记录或ID
     * @return bool
     */
    protected function isScheduleExpired($schedule)
    {
        if (is_numeric($schedule)) {
            $schedule = $this->model->find($schedule);
            if (!$schedule) {
                return true; // 如果记录不存在，视为已过期
            }
        }

        // 构建日期字符串
        $dateStr = $schedule['year'] . '-' .
            str_pad($schedule['month'], 2, '0', STR_PAD_LEFT) . '-' .
            str_pad($schedule['day'], 2, '0', STR_PAD_LEFT);

        // 转换为时间戳比较
        $scheduleDate = strtotime($dateStr);
        $today = strtotime(date('Y-m-d'));

        return $scheduleDate < $today;
    }


    public function _initialize()
    {
        parent::_initialize();
        $this->communityScheduler = new CommunityScheduler();
        $this->redis = new CommunityRedis();
        $this->model = new \app\common\model\CourseSchedule;
        $this->view->assign("courseList", $this->model::getCourseList(1, 3));
        $this->view->assign("communityList", $this->model::getCommunityList(1, 3));
        $this->view->assign("timeZoneList", $this->model::getTimeZoneList(1, 3));
        $this->view->assign("timeSlotList", $this->model::getTimeSlotList(1, 3));
        $this->view->assign("monthList", $this->model::getMonthList(1, 3));
        $this->view->assign("statusList", ['0' => __('Disabled'), '1' => __('Normal')]);

        // 获取公益项目列表
        $publicwelfareList = Db::name('fa_community_publicwelfare')
            ->where('status', 1)
            ->field('id, project_name')
            ->select();
        $this->view->assign("publicwelfareList", $publicwelfareList);
    }

    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */


    /**
     * 查看
     */
    public function index()
    {
        // 设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);

        // 获取项目ID参数
        $publicwelfare_id = $this->request->get('publicwelfare_id', 0);
        $community_id = $this->request->get('community_id', 0);


        // 获取当前登录用户信息
        $adminInfo =  $this->auth->getUserInfo();

        // 社区管理员权限控制：只能看到指定教学点及其子教学点的课程事件
        $allowedOcationIds = [];
        if (isset($adminInfo['group_id']) && $adminInfo['group_id'] == 8) {
            // 获取管理员关联的教学点ID
            $adminOcationId = null;
            if (isset($adminInfo['ocation_id']) && $adminInfo['ocation_id']) {
                $adminOcationId = $adminInfo['ocation_id'];
            } elseif (isset($_SESSION['think']['admin']['ocation_id']) && $_SESSION['think']['admin']['ocation_id']) {
                $adminOcationId = $_SESSION['think']['admin']['ocation_id'];
            }

            if ($adminOcationId) {
                // 获取该教学点及其所有子教学点的ID
                $allowedOcationIds = \app\admin\model\Ocation::getChildOcationIds($adminOcationId, true);

                // 如果没有指定community_id，使用管理员的教学点ID
                if (empty($community_id)) {
                    $community_id = $adminOcationId;
                }
            } else {
                // 如果社区管理员没有关联教学点，返回空结果
                if ($this->request->isAjax()) {
                    return json(["total" => 0, "rows" => []]);
                }
            }
        }

        // 获取城市和学校筛选参数
        $city_id = $this->request->get('city_id', 0);
        $school_id = $this->request->get('school_id', 0);
        $hasFormalSchedule = $this->model->isFormalSchedule($publicwelfare_id);
        // 完全避免使用pathinfo函数，直接使用已知的控制器和方法名
        // 这样可以避免警告出现
        if ($this->request->isAjax()) {
            // 如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            $isFormalSchedule = $this->hasFormalSchedule($publicwelfare_id);
            // 生成缓存键
            $search = $_REQUEST['search'] ?? '';
            $cacheKey = $this->redis->generateCacheKey($publicwelfare_id, $community_id, $search . '_city_' . $city_id . '_school_' . $school_id);

            // 尝试从Redis获取缓存数据
            $cachedResult = $this->redis->getCacheData($cacheKey);
            if ($cachedResult !== false && !empty($cachedResult["rows"]) && $adminInfo['group_id'] != 8) {
                header('isRedisCache: true');
                header('isFormalSchedule: ' . $hasFormalSchedule);
                $cachedResult['isFormalSchedule'] = $hasFormalSchedule;
                return json($cachedResult);
            } else if (!$isFormalSchedule) {
                header('generate: ' . $publicwelfare_id);
                $this->generate(true);
            }
            header('isRedisCache: false');
            header('isFormalSchedule: ' . $isFormalSchedule);
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            // 应用社区管理员权限控制
            if (isset($adminInfo['group_id']) && $adminInfo['group_id'] == 8 && !empty($allowedOcationIds)) {
                // 社区管理员：只能查看允许的教学点的课程事件
                $this->model = $this->model->where('ocation_id', 'in', $allowedOcationIds);
            } elseif ($community_id > 0) {
                // 其他管理员：按指定的community_id过滤
                $this->model = $this->model->where('ocation_id', $community_id);
            }

            // 只有当指定了具体项目id时，才添加过滤条件
            if ($publicwelfare_id > 0) {
                $this->model = $this->model->where('publicwelfare_id', $publicwelfare_id);
            } else {
                return json(["total" => 0, "rows" => []]);
            }

            // 添加城市和学校筛选条件
            if ($city_id > 0) {
                //$this->model = $this->model->where('city_id', $city_id);
            }
            if ($school_id > 0) {
                //$this->model = $this->model->where('school_id', $school_id);
            }

            $query = $this->model
                ->where($where);
            $query = $query->order('year', 'asc')  // 先按年份
                ->order('month', 'asc')  // 再按月份
                ->order('day', 'asc')
                ->order('timeslot', 'asc');

            // 一次性获取所有数据（移除分页限制）
            // 修改: 直接使用select()获取数组，避免使用collection转换提高性能
            $list = $query->select();
            // 修改: 如果$list不是数组则转换为数组
            if (!is_array($list)) {
                $list = $list->toArray();
            }

            // 优化: 预先获取所有需要的文本映射，避免在循环中重复查询
            $timeSlotTexts = [];
            $communityTexts = [];
            $timeZoneTexts = [];
            $courseTexts = [];

            // 收集所有需要查询的code
            $timeSlotCodes = [];
            $communityCodes = [];
            $timeZoneCodes = [];
            $courseCodes = [];
            $publicwelfareIds = [];

            foreach ($list as $v) {
                $timeSlotCodes[] = $v['time_slot_code'];
                $communityCodes[] = $v['community_code'];
                $timeZoneCodes[] = $v['time_zone_code'];
                $courseCodes[] = $v['course_code'];
                $publicwelfareIds[] = $v['publicwelfare_id'];
            }

            // 去重
            $timeSlotCodes = array_unique($timeSlotCodes);
            $communityCodes = array_unique($communityCodes);
            $timeZoneCodes = array_unique($timeZoneCodes);
            $courseCodes = array_unique($courseCodes);
            $publicwelfareIds = array_unique($publicwelfareIds);

            // 预查询所有需要的文本映射
            foreach ($publicwelfareIds as $pwId) {
                foreach ($timeSlotCodes as $code) {
                    $timeSlotTexts["{$pwId}_{$code}"] = CourseSchedule::getTimeSlotText($pwId, $code);
                }
                foreach ($communityCodes as $code) {
                    $communityTexts["{$pwId}_{$code}"] = CourseSchedule::getCommunityText($pwId, $code);
                }
                foreach ($timeZoneCodes as $code) {
                    $timeZoneTexts["{$pwId}_{$code}"] = CourseSchedule::getTimeZoneText($pwId, $code);
                }
                foreach ($courseCodes as $code) {
                    $courseTexts["{$pwId}_{$code}"] = CourseSchedule::getCourseText($pwId, $code);
                }
            }

            foreach ($list as $k => $v) {
                // 确保日期格式为YYYY-MM-DD（补零）
                $formattedDate = $list[$k]['year'] . '-' .
                    str_pad($list[$k]['month'], 2, '0', STR_PAD_LEFT) . '-' .
                    str_pad($list[$k]['day'], 2, '0', STR_PAD_LEFT);

                // 从预查询的结果中获取文本，避免重复查询数据库
                $timeSlotKey = "{$v['publicwelfare_id']}_{$v['time_slot_code']}";
                $communityKey = "{$v['publicwelfare_id']}_{$v['community_code']}";
                $timeZoneKey = "{$v['publicwelfare_id']}_{$v['time_zone_code']}";
                $courseKey = "{$v['publicwelfare_id']}_{$v['course_code']}";

                $list[$k]['time_slot_text'] = $formattedDate . " " .
                    (isset($timeSlotTexts[$timeSlotKey]) ? $timeSlotTexts[$timeSlotKey] : '') .
                    '(' . $v['time_slot_code'] . ")";
                $list[$k]['community_text'] = (isset($communityTexts[$communityKey]) ? $communityTexts[$communityKey] : '') .
                    '(' . $v['community_code'] . ")";
                $list[$k]['time_zone_text'] = (isset($timeZoneTexts[$timeZoneKey]) ? $timeZoneTexts[$timeZoneKey] : '') .
                    '(' . $v['time_zone_code'] . ")";
                $list[$k]['course_text'] = isset($courseTexts[$courseKey]) ? $courseTexts[$courseKey] : '';
                // 关键：加上is_formal字段
                $list[$k]['is_formal'] = isset($hasFormalSchedule) && $hasFormalSchedule ? true : false;

                // 检查事件是否已过期（不能编辑和删除）
                $list[$k]['is_expired'] = $this->isScheduleExpired($v);
            }
            //减少数组数量到10条
            //$list = array_slice($list, 0, 10);
            header('isFormalSchedule2: ' . $hasFormalSchedule);
            $result = array(
                "total" => count($list), // 使用数组长度获取总记录数
                "rows" => $list,
                "all_loaded" => true // 标记所有数据已加载
            );
            // 将结果缓存到Redis
            $this->redis->setCacheData($cacheKey, $result, 3600); // 缓存1小时

            return json($result);
            exit;
        }
        $this->assignconfig("isFormalSchedule", $hasFormalSchedule);
        $this->assign("isFormalSchedule", $hasFormalSchedule);
        $this->assign("publicwelfareId", $publicwelfare_id);
        header('isFormalSchedule2: ' . $hasFormalSchedule);
        // 明确指定模板地址，避免路径解析问题
        return $this->view->fetch('course/schedule/index');
    }

    /**
     * 获取学科列表
     * @param int $publicwelfare_id 项目ID
     * @return \think\response\Json
     */

    public function getSubjectList()
    {
        $publicwelfare_id = $this->request->param('publicwelfare_id', 0, 'intval');

        if (!$publicwelfare_id) {
            return json([]);
        }

        $list = Db::name('fa_community_course_config')
            ->where('publicwelfare_id', $publicwelfare_id)
            ->where('status', 1)
            ->field('id,code, name')
            ->select();

        $result = [];
        foreach ($list as $item) {
            $result[$item['code']] = $item['name'];
        }
        return json(['code' => 1, 'msg' => '获取成功', 'data' => $result]);
    }

    /**
     * 获取社区列表
     * @param int $publicwelfare_id 项目ID
     * @return \think\response\Json
     */
    public function getCommunityList()
    {
        $publicwelfare_id = $this->request->param('publicwelfare_id', 0, 'intval');

        if (!$publicwelfare_id) {
            return json([]);
        }

        $list = Db::name('fa_community_code_config')
            ->where('publicwelfare_id', $publicwelfare_id)
            ->where('status', 1)
            ->field('id, name')
            ->select();

        $result = [];
        foreach ($list as $item) {
            $result[$item['id']] = $item['name'];
        }

        return json(['code' => 1, 'msg' => '获取成功', 'data' => $result]);
    }

    protected function initialize()
    {
        parent::_initialize();
        $this->model = new \app\common\model\CourseSchedule;
        $this->view->assign("courseList", $this->model::getCourseList(1, 3));
        $this->view->assign("communityList", $this->model::getCommunityList(1, 3));
        $this->view->assign("timeZoneList", $this->model::getTimeZoneList(1, 3));
        $this->view->assign("timeSlotList", $this->model::getTimeSlotList(1, 3));
        $this->view->assign("monthList", $this->model::getTimeZoneList(1, 3));
        $this->view->assign("statusList", ['0' => __('Disabled'), '1' => __('Normal')]);

        // 获取公益项目列表
        $publicwelfareList = Db::name('fa_community_publicwelfare')
            ->where('status', 1)
            ->field('id, project_name')
            ->select();
        $this->view->assign("publicwelfareList", $publicwelfareList);

        // 注册API路由
        $this->noNeedLogin = ['getCommunityList', 'getSubjectList', 'confirmSchedule', 'checkFormalSchedule', 'cancelSchedule'];
        $this->noNeedRight = ['getCommunityList', 'getSubjectList', 'confirmSchedule', 'checkFormalSchedule', 'cancelSchedule'];
    }


    /**
     * 排课表格
     */
    public function table()
    {
        $publicwelfare_id = $this->request->param('publicwelfare_id');
        $this->communityScheduler->table($publicwelfare_id);
    }

    /**
     * 自动社区排课
     */
    public function generate($ispost = false)
    {
        $publicwelfare_id = $this->request->param('publicwelfare_id');
        $isFormalSchedule = $this->hasFormalSchedule($publicwelfare_id);
        header('isFormalSchedule1: ' . $isFormalSchedule . " " . $publicwelfare_id);
        if (!$isFormalSchedule && $publicwelfare_id != null && $publicwelfare_id > 0 && ($this->request->isPost() || $ispost)) {
            return $this->communityScheduler->generate($publicwelfare_id);
            return;
        }
        $this->view->assign('publicwelfare_id', $publicwelfare_id);
        return $this->view->fetch();
    }

    /**
     * 导出排课表
     */
    public function export()
    {
        $month = $this->request->get('month', date('n'));
        $year = $this->request->get('year', date('Y'));
        $communityId = $this->request->get('community_id', 0);
        $projectId = $this->request->get('project_id', 0);
        $courseId = $this->request->get('course_id', 0);

        // 获取当前登录用户信息
        $adminInfo = $this->auth->getUserInfo();

        // 社区管理员权限控制
        $allowedOcationIds = [];
        if (isset($adminInfo['group_id']) && $adminInfo['group_id'] == 8) {
            $adminOcationId = null;
            if (isset($adminInfo['ocation_id']) && $adminInfo['ocation_id']) {
                $adminOcationId = $adminInfo['ocation_id'];
            } elseif (isset($_SESSION['think']['admin']['ocation_id']) && $_SESSION['think']['admin']['ocation_id']) {
                $adminOcationId = $_SESSION['think']['admin']['ocation_id'];
            }

            if ($adminOcationId) {
                $allowedOcationIds = \app\admin\model\Ocation::getChildOcationIds($adminOcationId, true);
            }
        }

        // 获取当前月份的排课数据
        $query = $this->model
            ->where('month', $month)
            ->where('year', $year)
            ->where('status', 1);

        // 应用社区管理员权限控制
        if (isset($adminInfo['group_id']) && $adminInfo['group_id'] == 8 && !empty($allowedOcationIds)) {
            $query->where('ocation_id', 'in', $allowedOcationIds);
        }

        if ($communityId > 0) {
            $query->where('community_id', $communityId);
        }

        if ($projectId > 0) {
            $query->where('project_id', $projectId);
        }

        if ($courseId > 0) {
            $query->where('course_id', $courseId);
        }

        $scheduleData = $query->select();

        // 整理数据为表格格式
        $tableData = [];
        foreach ($scheduleData as $schedule) {
            $key = $schedule['time_slot_id'] . '_' . $schedule['community_id'] . '_' . $schedule['time_zone_id'];
            $tableData[$key] = $schedule['course_id'];
        }

        $courseList = $this->model::getCourseList();
        $communityList = $this->model::getCommunityList();
        $timeZoneList = $this->model::getTimeZoneList();
        $timeSlotList = $this->model::getTimeSlotList();

        // 创建Excel文件
        $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
        $worksheet = $spreadsheet->getActiveSheet();

        // 设置表头
        $worksheet->setCellValue('A1', $year . '年' . $month . '月排课表');
        $worksheet->mergeCells('A1:' . chr(65 + count($timeZoneList)) . '1');

        // 设置时区表头
        $worksheet->setCellValue('A2', '时间段/社区');
        for ($i = 0; $i < count($timeZoneList); $i++) {
            $worksheet->setCellValue(chr(66 + $i) . '2', $timeZoneList[$i]); // 修改为直接使用$i而不是$i+1
        }

        // 填充数据
        $row = 3;
        foreach ($timeSlotList as $timeSlotId => $timeSlotName) {
            foreach ($communityList as $communityId => $communityName) {
                $worksheet->setCellValue('A' . $row, $timeSlotName . ' ' . $communityName);

                for ($i = 0; $i < count($timeZoneList); $i++) {
                    $timeZoneId = $i + 1;
                    $key = $timeSlotId . '_' . $communityId . '_' . $timeZoneId;
                    $courseId = isset($tableData[$key]) ? $tableData[$key] : '';
                    $courseName = $courseId ? $courseId . ':' . $courseList[$courseId] : '';
                    $worksheet->setCellValue(chr(66 + $i) . $row, $courseName);
                }

                $row++;
            }
        }

        // 输出Excel文件
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="排课表_' . $year . '年' . $month . '月.xlsx"');
        header('Cache-Control: max-age=0');

        $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
        $writer->save('php://output');
        exit;
    }

    /**
     * 添加排课
     */
    public function add()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                try {
                    // 数据验证
                    if (empty($params['course_id'])) {
                        $this->error('请选择课程');
                    }
                    if (empty($params['community_id'])) {
                        $this->error('请选择社区');
                    }
                    if (empty($params['time_zone_id'])) {
                        $this->error('请选择时区');
                    }
                    if (empty($params['time_slot_id'])) {
                        $this->error('请选择时间段');
                    }
                    if (empty($params['month'])) {
                        $this->error('请选择月份');
                    }
                    if (empty($params['year'])) {
                        $this->error('请输入年份');
                    }

                    // 检查是否存在重复排课
                    $exists = $this->model
                        ->where('course_id', $params['course_id'])
                        ->where('community_id', $params['community_id'])
                        ->where('time_zone_id', $params['time_zone_id'])
                        ->where('time_slot_id', $params['time_slot_id'])
                        ->where('month', $params['month'])
                        ->where('year', $params['year'])
                        ->where('status', 'normal')
                        ->find();

                    if ($exists) {
                        $this->error('该时间段已存在排课，请选择其他时间');
                    }

                    // 设置默认值
                    $params['create_time'] = date('Y-m-d H:i:s');
                    $params['update_time'] = date('Y-m-d H:i:s');
                    $params['status'] = isset($params['status']) ? $params['status'] : 'normal';
                    $params['weigh'] = isset($params['weigh']) ? intval($params['weigh']) : 0;

                    // 插入 session 中的 city_id 和 school_id
                    if (isset($_SESSION['think']['admin']['city_id'])) {
                        $params['city_id'] = $_SESSION['think']['admin']['city_id'];
                    }
                    if (isset($_SESSION['think']['admin']['school_id'])) {
                        $params['school_id'] = $_SESSION['think']['admin']['school_id'];
                    }

                    // 清理不需要的字段
                    unset($params['delete_time']);

                    // 保存数据
                    $result = $this->model->allowField(true)->save($params);
                    if ($result !== false) {
                        // 清除相关缓存
                        if (isset($params['publicwelfare_id'])) {
                            $this->clearCacheByPublicwelfareId($params['publicwelfare_id']);
                        }
                        $this->success('添加成功');
                    } else {
                        $this->error($this->model->getError() ?: '添加失败');
                    }
                } catch (\think\exception\PDOException $e) {
                    $this->error('数据库错误：' . $e->getMessage());
                } catch (\think\Exception $e) {
                    $this->error('系统错误：' . $e->getMessage());
                }
            }
            $this->error('参数不能为空');
        }

        // GET请求，显示添加表单
        return $this->view->fetch();
    }

    /**
     * 编辑排课
     */
    public function edit($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error('记录不存在');
        }

        if ($this->request->isPost()) {
            // 检查事件是否已过期（只在提交时检查）
            if ($this->isScheduleExpired($row)) {
                $this->error('由于已经是到期或过期的项目，所以不能更改和删除');
            }
            $params = $this->request->post("row/a");
            if ($params) {
                try {
                    // 数据验证
                    if (empty($params['course_id'])) {
                        $this->error('请选择课程');
                    }
                    if (empty($params['community_id'])) {
                        $this->error('请选择社区');
                    }
                    if (empty($params['time_zone_id'])) {
                        $this->error('请选择时区');
                    }
                    if (empty($params['time_slot_id'])) {
                        $this->error('请选择时间段');
                    }
                    if (empty($params['month'])) {
                        $this->error('请选择月份');
                    }
                    if (empty($params['year'])) {
                        $this->error('请输入年份');
                    }

                    // 检查是否存在重复排课（排除当前记录）
                    $exists = $this->model
                        ->where('course_code', $params['course_id'])
                        ->where('community_code', $params['community_id'])
                        ->where('time_zone_code', $params['time_zone_id'])
                        ->where('time_slot_code', $params['time_slot_id'])
                        ->where('month', $params['month'])
                        ->where('day', $params['day'])
                        ->where('year', $params['year'])
                        ->where('status', '1')
                        ->where('id', '<>', $ids)
                        ->find();

                    if ($exists) {
                        $this->error('该时间段已存在排课，请选择其他时间');
                    }

                    // 设置更新时间
                    $params['update_time'] = date('Y-m-d H:i:s');
                    $params['status'] = isset($params['status']) ? $params['status'] : '1';
                    $params['weigh'] = isset($params['weigh']) ? intval($params['weigh']) : 0;

                    // 插入 session 中的 city_id 和 school_id
                    if (isset($_SESSION['think']['admin']['city_id'])) {
                        $params['city_id'] = $_SESSION['think']['admin']['city_id'];
                    }
                    if (isset($_SESSION['think']['admin']['school_id'])) {
                        $params['school_id'] = $_SESSION['think']['admin']['school_id'];
                    }

                    // 清理不需要的字段
                    unset($params['delete_time']);
                    unset($params['create_time']);
                    $params['update_time'] = strtotime($params['update_time']);

                    // 更新数据
                    $result = $row->allowField(true)->save($params);
                    if ($result !== false) {
                        // 清除相关缓存
                        if (isset($params['publicwelfare_id'])) {
                            $this->clearCacheByPublicwelfareId($params['publicwelfare_id']);
                        } else {
                            // 如果没有publicwelfare_id参数，从原记录中获取
                            $this->clearCacheByPublicwelfareId($row['publicwelfare_id']);
                        }
                        $this->success('更新成功');
                    } else {
                        $this->error($row->getError() ?: '更新失败');
                    }
                } catch (\think\exception\PDOException $e) {
                    $this->error('数据库错误：' . $e->getMessage());
                } catch (\think\Exception $e) {
                    $this->error('系统错误：' . $e->getMessage());
                }
            }
            $this->error('参数不能为空');
        }
        $row['course_id'] = db("fa_community_course_config")->where('code', $row['course_code'])->where("publicwelfare_id", $row['publicwelfare_id'])->value('id');
        $row['community_id'] = db("fa_community_code_config")->where('code', $row['community_code'])->where("publicwelfare_id", $row['publicwelfare_id'])->value('id');
        $row['time_zone_id'] = db("fa_community_timezone_config")->where('code', $row['time_zone_code'])->where("publicwelfare_id", $row['publicwelfare_id'])->value('id');
        $row['time_slot_id'] = db("fa_community_timeslot_config")->where('code', $row['time_slot_code'])->where("publicwelfare_id", $row['publicwelfare_id'])->value('id');
        // GET请求，显示编辑表单
        // 检查是否过期并传递给视图
        $isExpired = $this->isScheduleExpired($row);
        $this->view->assign("row", $row);
        $this->view->assign("isExpired", $isExpired);
        return $this->view->fetch();
    }

    /**
     * 清空项目排期
     */
    public function clear()
    {
        $publicwelfare_id = $this->request->post('publicwelfare_id', 0);

        if (!$publicwelfare_id) {
            $this->error('请选择要清空排期的项目');
        }

        try {
            // 物理删除指定项目的排期记录
            $result = $this->model
                ->where('publicwelfare_id', $publicwelfare_id)->delete();

            if ($result === false) {
                throw new Exception('删除操作失败');
            }
            db::name('fa_course_table_autoplan_temp')->where('publicwelfare_id', $publicwelfare_id)->delete();
            //db::name('eb_classes')->where('publicwelfare_id', $publicwelfare_id)->delete();

            // 清除相关缓存
            $this->redis->clearCacheByPublicwelfareId($publicwelfare_id);
            header("clearCache_publicwelfare_id: " . $publicwelfare_id);
            $this->success('清空项目排期成功');
        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    /**
     * 删除排课记录（物理删除）
     */
    public function del($ids = null)
    {
        if (!$this->request->isPost()) {
            $this->error('非法请求');
        }

        $ids = $ids ? $ids : $this->request->post("ids");
        if (empty($ids)) {
            $this->error('参数不能为空');
        }

        $pk = $this->model->getPk();
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            $this->model->where($this->dataLimitField, 'in', $adminIds);
        }

        $list = $this->model->where($pk, 'in', $ids)->select();
        if (!$list) {
            $this->error('记录不存在');
        }

        // 检查是否有过期的事件
        foreach ($list as $item) {
            if ($this->isScheduleExpired($item)) {
                $this->error('由于已经是到期或过期的项目，所以不能更改和删除');
            }
        }

        try {
            // 获取要删除的记录信息，用于清除缓存
            $deletedRecords = $this->model->where($pk, 'in', $ids)->select();
            $publicwelfareIds = [];
            foreach ($deletedRecords as $record) {
                if (!in_array($record['publicwelfare_id'], $publicwelfareIds)) {
                    $publicwelfareIds[] = $record['publicwelfare_id'];
                }
            }

            // 执行物理删除
            $count = $this->model->where($pk, 'in', $ids)->delete();

            if ($count === false) {
                throw new Exception('删除操作失败');
            }

            // 清除相关缓存
            foreach ($publicwelfareIds as $publicwelfareId) {
                $this->clearCacheByPublicwelfareId($publicwelfareId);
            }

            $this->success('删除成功', null, ['deleted_count' => $count, 'skip_cache' => 1]);
        } catch (Exception $e) {
            $this->error('删除失败：' . $e->getMessage());
        }
    }



    /**
     * 正式排课 - 将Autoplantemp数据导入到正式表
     */
    public function confirmSchedule()
    {
        if (!$this->request->isPost()) {
            $this->error('非法请求');
        }

        $publicwelfare_id = $this->request->post('publicwelfare_id', 0);

        if (!$publicwelfare_id) {
            $this->error('请选择要正式排课的项目');
        }

        try {
            // 检查是否已存在正式排课记录
            $existCount = Db::name('fa_course_table_autoplan')
                ->where('publicwelfare_id', $publicwelfare_id)
                ->count();

            if ($existCount > 0) {
                $this->error('该项目已存在正式排课记录，无法重复导入');
            }

            // 获取Autoplantemp中该项目的所有记录
            $tempRecords = Db::name('fa_course_table_autoplan_temp')
                ->where('publicwelfare_id', $publicwelfare_id)
                ->select();

            if (empty($tempRecords)) {
                $this->error('该项目暂无排课记录可导入');
            }

            // 准备插入正式表的数据
            $formalData = [];
            foreach ($tempRecords as $record) {
                $record['create_time'] = time();
                $record['update_time'] = time();
                $record['t_id'] = $record['id'];
                unset($record['id']);
                $formalData[] = $record;
            }

            // 使用insertAll方法导入到正式表
            $result = Db::name('fa_course_table_autoplan')->insertAll($formalData);
            Db::name('fa_course_table_autoplan_temp')->where('publicwelfare_id', $publicwelfare_id)->delete();
            if ($result === false) {
                throw new Exception('导入正式排课表失败');
            }
            $this->success('正式排课成功，共导入 ' . count($formalData) . ' 条记录');
        } catch (Exception $e) {
            $this->error('正式排课失败：' . $e->getMessage());
        }
    }

    /**
     * 检查项目是否已有正式排课记录
     */
    public function checkFormalSchedule()
    {
        $publicwelfare_id = $this->request->param('publicwelfare_id', 0);

        if (!$publicwelfare_id) {
            return json(['code' => 0, 'msg' => '参数错误']);
        }

        $count = Db::name('fa_course_table_autoplan')
            ->where('publicwelfare_id', $publicwelfare_id)
            ->count();

        return json([
            'code' => 1,
            'data' => ['has_formal' => $count > 0],
            'msg' => '查询成功'
        ]);
    }

    /**
     * 统一的重复检查逻辑
     */
    private function checkDuplicateSchedule($params, $excludeId = null)
    {
        $query = $this->model
            ->where('course_code', $params['course_code'])
            ->where('community_code', $params['community_code'])
            ->where('time_zone_code', $params['time_zone_code'])
            ->where('time_slot_code', $params['time_slot_code'])
            ->where('year', $params['year'])
            ->where('month', $params['month'])
            ->where('day', $params['day'])
            ->where('status', 1);

        if ($excludeId) {
            $query->where('id', '<>', $excludeId);
        }

        return $query->find();
    }

    /**
     * 根据ocation_id获取社区id
     * 复制自Community控制器的findCommunityId方法
     */
    private function findCommunityId($ocation_id)
    {
        // 先直接查询
        $community_id = Db::name('eb_school_community')
            ->where('ocation_id', $ocation_id)
            ->value('community_id');

        if ($community_id) {
            return $community_id;
        }

        // 如果没有直接记录，通过父级教学点递归查找
        return $this->findCommunityIdRecursive($ocation_id);
    }

    /**
     * 取消正式排课
     */
    public function cancelSchedule()
    {
        if (!$this->request->isPost()) {
            return json([
                'code' => 0,
                'msg' => '非法请求方式',
                'data' => null,
                'url' => null,
                'wait' => 3
            ]);
        }

        $publicwelfare_id = $this->request->post('publicwelfare_id', 0);
        $password = $this->request->post('password', '');

        if (!$publicwelfare_id) {
            \think\Log::record('cancelSchedule失败：项目ID为空', 'error');
            return json([
                'code' => 0,
                'msg' => '项目ID不能为空',
                'data' => null,
                'url' => null,
                'wait' => 3
            ]);
        }

        // 验证密码
        if (!$this->validateSchedulePassword($password)) {
            \think\Log::record('cancelSchedule失败：密码验证失败 publicwelfare_id=' . $publicwelfare_id, 'error');
            return json([
                'code' => 0,
                'msg' => '密码错误，无法执行取消正式排课操作',
                'data' => null,
                'url' => null,
                'wait' => 3
            ]);
        }

        // 记录操作开始
        $userId = 0;
        try {
            $user = $this->auth->getUserInfo();
            $userId = is_array($user) && isset($user['id']) && is_scalar($user['id']) ? $user['id'] : 0;
        } catch (\Exception $e) {
            $userId = 0;
        }

        \think\Log::record('开始取消正式排课 publicwelfare_id=' . $publicwelfare_id . ' user_id=' . $userId, 'info');

        // 开始事务
        Db::startTrans();
        try {
            // 检查项目是否存在
            $project = Db::name('fa_community_publicwelfare')
                ->where('id', $publicwelfare_id)
                ->find();

            if (!$project) {
                Db::rollback();
                \think\Log::record('cancelSchedule失败：项目不存在 publicwelfare_id=' . $publicwelfare_id, 'error');
                return json([
                    'code' => 0,
                    'msg' => '指定的项目不存在',
                    'data' => null,
                    'url' => null,
                    'wait' => 3
                ]);
            }

            // 检查正式表中是否有数据
            $formalCount = Db::name('course_table_autoplan')
                ->where('publicwelfare_id', $publicwelfare_id)
                ->count();

            if ($formalCount == 0) {
                Db::rollback();
                \think\Log::record('cancelSchedule失败：正式表无数据 publicwelfare_id=' . $publicwelfare_id, 'error');
                return json([
                    'code' => 0,
                    'msg' => '该项目没有正式排课数据，无需取消',
                    'data' => null,
                    'url' => null,
                    'wait' => 3
                ]);
            }

            \think\Log::record('找到正式排课数据 publicwelfare_id=' . $publicwelfare_id . ' count=' . $formalCount, 'info');

            // 删除正式表中的数据
            \think\Log::record('开始删除正式排课数据 publicwelfare_id=' . $publicwelfare_id, 'info');

            $deleteResult = Db::name('course_table_autoplan')
                ->where('publicwelfare_id', $publicwelfare_id)
                ->delete();

            if ($deleteResult === false) {
                throw new \Exception('删除正式排课数据失败');
            }

            \think\Log::record('删除正式排课数据成功 publicwelfare_id=' . $publicwelfare_id . ' deleted_count=' . $deleteResult, 'info');

            // 清除相关缓存
            $this->redis->clearCacheByPublicwelfareId($publicwelfare_id);
            // 提交事务
            Db::commit();

            // 记录成功日志
            \think\Log::record('取消正式排课成功 publicwelfare_id=' . $publicwelfare_id . ' deleted_count=' . $deleteResult . ' user_id=' . $userId, 'info');

            $message = '取消正式排课成功，共删除 ' . $deleteResult . ' 条记录';
            return json([
                'code' => 1,
                'msg' => $message,
                'data' => [
                    'publicwelfare_id' => $publicwelfare_id,
                    'deleted_count' => $deleteResult,
                    'project_name' => $project['project_name'] ?? ''
                ],
                'url' => null,
                'wait' => 3
            ]);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();

            // 记录详细错误日志
            \think\Log::record('取消正式排课失败 publicwelfare_id=' . $publicwelfare_id . ' error=' . $e->getMessage() . ' user_id=' . $userId, 'error');

            return json([
                'code' => 0,
                'msg' => '取消正式排课失败：' . $e->getMessage(),
                'data' => null,
                'url' => null,
                'wait' => 3
            ]);
        }
    }

    /**
     * 验证正式排课密码
     * @param string $password 用户输入的密码
     * @return bool
     */
    private function validateSchedulePassword($password)
    {
        // 设置正式排课密码（可以从配置文件或数据库读取）
        $correctPassword = config('schedule_password') ?: '1594561';

        // 临时调试日志 - 记录密码验证详情
        \think\Log::record('密码验证调试 - 输入密码: [' . $password . '] 长度: ' . strlen($password) . ' 正确密码: [' . $correctPassword . '] 长度: ' . strlen($correctPassword), 'info');
        \think\Log::record('密码验证调试 - 输入密码十六进制: ' . bin2hex($password) . ' 正确密码十六进制: ' . bin2hex($correctPassword), 'info');

        $result = $password === $correctPassword;
        \think\Log::record('密码验证调试 - 验证结果: ' . ($result ? '通过' : '失败'), 'info');

        return $result;
    }

    /**
     * 检查指定table_id是否已有正式排课记录（内部方法）
     * @param int $table_id 项目ID
     * @return bool
     */
    private function hasFormalSchedule($publicwelfare_id)
    {
        if (empty($publicwelfare_id)) {
            return false;
        }

        $count = Db::name('course_table_autoplan')
            ->where('publicwelfare_id', $publicwelfare_id)
            ->count();

        return $count > 0 ? true : false;
    }
}
